package com.heima.media.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.dto.ResponseResult;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.minio.MinIOService;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.media.dto.ArticleDto;
import com.heima.media.dto.ContentDto;
import com.heima.media.dto.ImageDto;
import com.heima.media.entity.WmChannel;
import com.heima.media.entity.WmNews;
import com.heima.media.entity.WmSensitive;
import com.heima.media.entity.WmUser;
import com.heima.media.feign.ApArticleClients;
import com.heima.media.service.*;
import org.apache.commons.io.IOUtils;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class AuditServiceimpl implements IAuditService {

    /**
     * 审核
     * @param wmNews
     */
    @Override
    @Async
    public void audit(WmNews wmNews) {

        System.err.println(Thread.currentThread().getName()+"审核开始......"
        +"文章id为:"+wmNews.getId());

        // 如果状态是8 开始进入文章发布
        if (wmNews.getStatus() == 8) {
            saveArticle(wmNews);
            return;
        }

        

        if (wmNews.getStatus()==1){
            //提取文本的图片和内容
            Map<String,Object>map=getTextAndImagesFromContent(wmNews.getContent());
            //提取文字
            String text = (String) map.get("text");

            //提取图片
            List<String> images = (List<String>) map.get("images");

            //先进性 本地敏感词库匹配
            boolean sensResult=checkSens(wmNews,text);
            if (!sensResult)return;
            //阿里云文字审核
           Boolean checkText= checkText(wmNews,text);
           if (!checkText)return;

           //阿里云图片审核

            List<ImageDto> coverImages = JSON.parseArray(wmNews.getImages(), ImageDto.class);
            //可能封面与内容图片不符合
            for (ImageDto image : coverImages) {
                if (!images.contains(image.getUrl())){
                    images.add(image.getUrl());
                }
            }
            //图片审核
            boolean imageResult=checkImage(wmNews,images);
            if (!imageResult)return;
            System.err.println(Thread.currentThread().getName()+"审核完成"
                    +"文章id为:"+wmNews.getId());

            //判断是否立即发布任务,判断当前时间是否大于文章的发布时间
            if (System.currentTimeMillis()<wmNews.getPublishTime().getTime()){
                sendDelayMessage(wmNews);
            }else {

            //调用文章服务保存文章
            saveArticle(wmNews);
            }



        }
    }

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 发送延迟任务(消息)
     *
     * @param wmNews
     */
    private void sendDelayMessage(WmNews wmNews) {

        wmNews.setStatus(8);
        wmUsersService.updateById(wmNews);
        // 创建阻塞队列
        RBlockingQueue<String> blockingQueue = redissonClient.getBlockingQueue("article_publish");
        // 创建延迟队列
        RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);
        // 发送延迟消息 参数为:  1 发送的消息  2 延迟时间  3 时间单位
        // 需要延迟的时间为  发布时间 - 当前系统时间
        long time = wmNews.getPublishTime().getTime() - System.currentTimeMillis();
        delayedQueue.offer(JSON.toJSONString(wmNews), time, TimeUnit.MILLISECONDS);
        System.out.println("消息发送完成" + new Date());

    }


    @Autowired
    private IWmSensitiveService wmSensitiveService;
    /**
     * 本地敏感词匹配验证
     * @param wmNews
     * @param text
     * @return
     */
    private boolean checkSens(WmNews wmNews, String text) {
        //初始化
        if (SensitiveWordUtil.dictionaryMap.size()==0){
            LambdaQueryWrapper<WmSensitive> query = new LambdaQueryWrapper<>();
            query.select(WmSensitive::getSensitives);
            List<String> list = wmSensitiveService.listObjs(query, o -> o.toString());
            SensitiveWordUtil.initMap(list);
        }
        Map<String, Integer> map = SensitiveWordUtil.matchWords(wmNews.getTitle() + wmNews.getLabels() + text);
        if (map.size()>0){
            wmNews.setStatus(2);
            Set<String> keySet = map.keySet();
            String join = String.join("," + keySet);
            wmNews.setReason("本地敏感词审核不通过"+join);
            wmUsersService.updateById(wmNews);
            return false;
        }
        return true;
    }


    @Autowired
   private ApArticleClients articleClients;
    @Autowired
    private IWmUserService iWmUserService;

    @Autowired
    IWmChannelService iWmChannelService;
    /**
     * 保存文章
     * @param wmNews
     */
    private void saveArticle(WmNews wmNews) {
        ArticleDto dto=new ArticleDto();
        dto.setTitle(wmNews.getTitle());
        //查询wm_user 表,作者信息
        WmUser wmUser = iWmUserService.getById(wmNews.getUserId());
        dto.setAuthorId(wmUser.getApAuthorId());
        dto.setAuthorName(wmUser.getName());
        dto.setChannelId(wmNews.getChannelId());
        //查询频道名称
        WmChannel wmChannel = iWmChannelService.getById(wmNews.getChannelId());
        dto.setChannelName(wmChannel.getName());
        dto.setLayout(wmNews.getType());
        dto.setFlag(0);

        List<ImageDto> list = JSON.parseArray(wmNews.getImages(), ImageDto.class);
        List<String> images = new ArrayList<>();
        for (ImageDto imageDto : list) {
            images.add(imageDto.getUrl());
        }
        String join = String.join(",", images);
        dto.setImages(join);
        dto.setContent(wmNews.getContent());
        ResponseResult<Long> longResponseResult = articleClients.saveArticle(dto);
        if (longResponseResult.getCode().equals(AppHttpCodeEnum.SUCCESS.getCode())){
            Long data = longResponseResult.getData();
            if (data!=null){
                wmNews.setArticleId(data);
                wmNews.setStatus(9);
                wmUsersService.updateById(wmNews);
            }
        }

    }

    @Autowired
    private MinIOService minIOService;

    @Autowired
    private GreenImageScan imageScan;
    /**
     * 阿里云图片审核
     * @param wmNews
     * @param images
     * @return
     */
    private boolean checkImage(WmNews wmNews, List<String> images) {
        boolean result=false;
        //如果没有图片
        if (images.size()==0){
            return true;
        }
        try {
            //minio在外网上,需要先下载 再去阿里审核
        List<byte[]> imagesList = new ArrayList<>();
        //遍历图片集合
        for (String image : images) {
            //如果图片不为空
            if (!StringUtils.isEmpty(image)){
                //上传minio
                InputStream inputStream = minIOService.download(image);
                //流转换为字节数组
                byte[] bytes = IOUtils.toByteArray(inputStream);
                imagesList.add(bytes);
            }
            }

        //进行图片审核
            Map map = imageScan.imageScan(imagesList);
        //取出结果
            String suggestion = (String) map.get("suggestion");

            //
            switch (suggestion){
                //审核成功
                case "pass":
                    result=true;
                    break;
                    //审核失败
                case "block":
                    wmNews.setStatus(2);
                    wmNews.setReason("阿里图片审核失败:"+map.get("label"));
                    wmUsersService.updateById(wmNews);
                    break;
                    //人工审核
                case "review":
                    wmNews.setStatus(3);
                    wmUsersService.updateById(wmNews);
                    break;
            }
        } catch (Exception e) {
                    e.printStackTrace();
        }

        return result;
    }

    @Autowired
    private GreenTextScan greenTextScan;

    @Autowired
    private IWmNewsService wmUsersService;
    /**
     * 文字审核
     * @param wmNews
     * @param text
     * @return
     */
    private Boolean checkText(WmNews wmNews, String text) {
        boolean result=false;
        //审核内容: 标签+标题+内容
        text=wmNews.getTitle()+wmNews.getLabels()+text;
        try {

            Map map = greenTextScan.greenTextScan(text);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion){
                //审核成功
                case "pass":
                    result=true;
                    break;
                    //审核不成功
                case "block":
                    wmNews.setStatus(2);
                    wmUsersService.updateById(wmNews);
                    wmNews.setReason("阿里云文本审核失败:"+map.get("label"));
                    break;
                    //人工审核
                case "review":
                    wmNews.setStatus(3);
                    wmUsersService.updateById(wmNews);
                    break;

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }


    /**
     * 提取内容: 文本和图片
     * @param content
     * @return
     */
    private Map<String, Object> getTextAndImagesFromContent(String content) {
        HashMap<String, Object> map = new HashMap<>();
        StringBuilder sb = new StringBuilder();
        ArrayList<Object> images = new ArrayList<>();
        List<ContentDto> dtos = JSON.parseArray(content, ContentDto.class);
        for (ContentDto dto : dtos) {
            if (dto.getType().equals("text")){
                sb.append(dto.getValue());
            }else {
                if (!StringUtils.isEmpty(dto.getValue())){
                    images.add(dto.getValue());
                }
            }
        }
        map.put("text",sb.toString());
        map.put("images",images);
        return map;
    }
}
